package mapper

import (
	"fmt"
	"gorm.io/gorm"
	"mall/services/distributed-id/rpc/internal/mapper/entity"
	"time"
)

// SegmentRepo -.
type SegmentRepo struct {
}

// NewSegmentRepo -.
func NewSegmentRepo() *SegmentRepo {
	return &SegmentRepo{}
}

// GetList -.
func (r *SegmentRepo) GetList(db *gorm.DB) ([]entity.Segments, error) {
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	var s []entity.Segments
	if findTx := tx.Find(&s); findTx.Error != nil {
		return s, fmt.Errorf("SegmentRepo - GetList - Find: %w", findTx.Error)
	}
	return s, nil
}

// Add -.
func (r *SegmentRepo) Add(db *gorm.DB, s *entity.Segments) error {
	tx := db.Debug()
	count := int64(0)
	tx.Where("biz_tag = ?", s.BizTag).Count(&count)
	if count > 0 {
		return fmt.Errorf("SegmentRepo - Add - Exist: %s", s.BizTag)
	}
	now := time.Now()
	s.CreateTime = &now
	s.UpdateTime = &now
	tx = tx.Create(s)
	if tx.Error != nil {
		return fmt.Errorf("SegmentRepo - Add - Insert: %w", tx.Error)
	}
	return nil
}

// GetNextId -.
func (r *SegmentRepo) GetNextId(db *gorm.DB, tag string) (*entity.Segments, error) {
	resp := &entity.Segments{}
	err := db.Transaction(func(tx *gorm.DB) error {
		updateTx := tx.Exec("update segments set max_id=max_id+step, update_time = ? where biz_tag = ?", time.Now(), tag)
		if updateTx.Error != nil {
			return updateTx.Error
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	queryTx := db.Where("biz_tag = ?", tag).First(resp)
	if queryTx.Error != nil {
		return nil, queryTx.Error
	}
	return resp, nil
}
